;(function(Ext,exports){
	Ext.Loader.setPath("Ext.ux.LayuiIconPicker",contextPath+"pickers/LayuiIconPicker.js");
	Ext.Loader.setPath("Ext.ux.FaIconPicker",contextPath+"pickers/FaIconPicker.js");
	
	Ext.require('Ext.ux.LayuiIconPicker');
	Ext.require('Ext.ux.FaIconPicker');
	var FormFieldUtil={}, timeFormatMap={
			'yyyy-MM-dd hh:mm:ss':'Y-m-d h:i:s',
			'yyyy-MM-dd':'Y-m-d',
			'yyyy-MM':'Y-m',
			'yyyy':'Y',
			'yyyy年MM月dd日':'Y年m月d日'
	};
	FormFieldUtil.booleanStore=Ext.create('Ext.data.Store',{
		data:[{
			name:"true",text:"是",
		},{
			name:"false",text:"否"
		}],
		fields:['name','text']
	});
	FormFieldUtil.getSearchFormFields=function(metaId,metaData,fs){
		var refMetaMap=metaData["refMetaMap"],
		mainMeta=refMetaMap[metaId],
		fields=mainMeta["fields"],fm=mainMeta["fieldMap"],refEnumMap=metaData["refEnumMap"];
		if(!fm){
			fm={};
			Ext.iterate(fields,function(f,i){
				fm[f["name"]]=f;
			});
			mainMeta["fieldMap"]=fm;
		}
		var items=[];
		if(fs){
			Ext.iterate(fs,function(name,i){
				var field=fm[name];
				if(field){
					var name=field["name"],text=field["text"],type=field["type"],attrs=field["attrs"],
					enums=attrs["enums"],picker=attrs["picker"],
					item={labelAlign:'right',xtype:"textfield",fieldLabel:text,name:name};
					items.push(item);
					if(picker){
						if(picker=="treepicker"){
							var refModelId=attrs["refModelId"],
							refModel=refMetaMap[refModelId],
							refModelAttrs=refModel["attrs"],
							rootId=refModelAttrs["rootId"]||refModelId,
							idProperty=refModelAttrs["idProperty"]||"id",
							seqProperty=refModelAttrs["seqProperty"]||"seq",
							parentIdProperty=refModelAttrs["parentIdProperty"],
							action=refModelAttrs["action"]||{url:contextPath+"meta/record/"+refModelId,type:'rest'},
							query=refModelAttrs["query"]||action,
							dataUrl=query["url"]||(contextPath+"meta/record/getTree/"+refModelId);
							Ext.apply(item,{
								xtype:'treepicker',
								queryMode:'remote',
								store:Ext.create('Ext.data.TreeStore', {
								    defaultRootId: rootId,
								    parentIdProperty:parentIdProperty,
								    nodeParam:idProperty,
								    sorters: [{ property: seqProperty, direction: 'ASC' }],
								    proxy: {
								    	url:dataUrl,
								        type: 'rest',
								        actionMethods: { read: 'GET' }
								    }

								}),
								emptyText:"--请选择--",
								valueField:attrs["valueField"]||"code",
								displayField:attrs["displayField"]||"text",
								forceSelection:false,
								scrollable: true,
		                        minPickerHeight: 200,
		                        value: '' 
							});
						}
					}else{
						if(enums){
							enums=enums.substring(enums.indexOf("$")+1);
							item["xtype"]='combo';
							item["name"]=name;
							item["queryMode"]='local';
							item["triggerAction"]='all';
							item["valueField"]=attrs["valueField"]||"code";
							item["displayField"]=attrs["displayField"]||"text";
							item["store"]={
									fields:["sid","name","code","text"],
									data:refEnumMap[enums]["list"]
							};
						}else{
							item["name"]=name;
							switch(type){
							case -5:
							case 4:
								item["xtype"]="numberfield";
								item["allowNull"]=true;
								item["allowBlank"]=true;
								break;
							case 1:
								break;
							case 12:
								item["xtype"]='textarea';
								item["minHeight"]=60;
								break;
							case 16:
							Ext.apply(item,{
					            xtype: 'radiogroup',
					            cls: 'x-check-group-alt',
					            columns: 3,
					            items: [
					                {boxLabel: '是', inputValue: true},
					                {boxLabel: '否', inputValue: false}
					            ]
					        });
								break;
							case 91:
								var format='Y-m-d';
								var xtype="datefield";
							case 92:
								xtype='timefield';
								format='h:i:s';
							case 93:
								item["xtype"]='fieldcontainer';
								xtype="datefield";
								format="Y-m-d h:i:s";
								if(attrs["dataformat"]){
									format=timeFormatMap[attrs["dataformat"]]
								}
								Ext.apply(item,{
									 combineErrors: true,
								        msgTarget : 'side',
								        layout: 'hbox',
								        defaults: {
								            flex: 1,
								            hideLabel: true
								        },
								        items: [{
								            xtype: xtype,
								            name: name+'.start',
								            format:format,
								            margin: '0 5 0 0'
								        },{xtype: 'displayfield', value: '-'}, {
								            xtype     : xtype,
								            format:format,
								            name      : name+'.end',
								            margin: '0 5 0 5'
								        }]
								});
								break;
							}
						}
					}
					
				}
				
				
			});
		}
		
		return items;
	};
	
	FormFieldUtil.getSegmentedButton=function(name,field,metaData){
		var refEnumMap=metaData["refEnumMap"],attrs=field["attrs"],enums=attrs["enums"],
		item={"xtype":"fieldcontainer",fieldLabel:field["text"]},itemid=name.replace(/\./g,'_');
		var seg={
				xtype:"segmentedbutton",
				itemId:itemid,
				items:[],
				allowDepress:true,
				defaults:{
					enableToggle:true,
					name:name
				},
			     listeners: {
			          toggle: function(container, button, pressed) {
			        	  var f=this.up('form').getForm().findField(name);
			        	  f.setValue(container.getValue());
			          }
			     }
			};
		var xitems=item["items"]=[seg];
		var enumdata=refEnumMap[enums],list=enumdata["list"],
		options=seg["items"];
		xitems.push({
			name:name,
			xtype:'hidden',
			listeners:{
				'change' :function (f, newValue, oldValue, eOpts ) {
					var c=this.up('form').down("#"+itemid);
					if(newValue){
						c.setValue(newValue);
					}else{
						var v=c.getValue();
						if(v){
							var bs=c.query("[value="+v+"]");
							if(bs.length>0){
								bs[0].setPressed(false);
							}
						}
					}
				}
			
			}
		});
		Ext.iterate(list,function(option,i){
				options.push({
					value:option["code"],
					iconCls:option["name"],
					tooltip:option["text"]
				});
		});
		return item;
	};
	
	FormFieldUtil.getTreePicker=function(field,metaData){
		var item={"xtype":"treepicker",name:field["name"]};
		Ext.require['Ext.ux.TreePicker'];
		var attrs=field["attrs"]||{},
		refMetaMap=metaData['refMetaMap'],
		refModelId=attrs["refModelId"],
		refModel=refMetaMap[refModelId],
		refModelAttrs=refModel["attrs"],
		rootId=attrs["rootId"]||(refModelAttrs["rootId"]||refModelId),
		seqProperty=refModelAttrs["seqProperty"]||"seq",
		parentIdProperty=refModelAttrs["parentIdProperty"]||"fid",
		action=refModelAttrs["action"]||{url:contextPath+"meta/record/"+refModelId,type:'rest'},
		query=refModelAttrs["query"]||action,
		dataUrl=(contextPath+"meta/getAllChildren/"+refModelId);
		Ext.apply(item,{
			xtype:'treepicker',
			queryMode:'remote',
			fieldLabel:field["text"],
			store:Ext.create('Ext.data.TreeStore', {
				autoLoad :true,
				rootVisible:false,
			    root:{
			    	id:rootId,
			    	text:refModelAttrs["rootText"]||refModel["text"],
			    	expanded:true
			    },
			    parentIdProperty:parentIdProperty,
			    sorters: [{ property: seqProperty, direction: 'ASC' }],
			    proxy: {
			    	url:dataUrl,
			        type: 'rest',
			        actionMethods: { read: 'GET' }
			    }
			}),
			
			displayField:refModelAttrs["displayField"]||"text",
			forceSelection:false,
			scrollable: true,
            minPickerHeight: 200,
            value: '' 
		});
		return item;
	};
	
	FormFieldUtil.getTrigger=function(field,metaData){
		var attrs=field["attrs"],
		picker=attrs["picker"],
		item={xtype:"textfield",fieldLabel:field["text"],name:field["name"]};
		item["triggers"]={
				"trigger1":{
					handler:function(){
						var ctrl=this;
						Ext.create({
							valueHolder:ctrl,
							xtype:picker,
							modal:true
						}).show();
					}
				}
		};
		return item;
	};
	
	FormFieldUtil.typeMap={
		"-5":"number",
		"4":"number",
		"1":"string",
		"12":"string",
		"91":"date",
		"92":"time",
		"93":"date",
		"16":"boolean"
	};
	
	FormFieldUtil.getSubModelFields=function(fs,mainMetaId,metaData,prefix){
		var refMetaMap=metaData["refMetaMap"],mainMeta=refMetaMap[mainMetaId],sfields=mainMeta["fields"],
		typeMap=FormFieldUtil.typeMap,prefix=prefix||"";
		Ext.iterate(sfields,function(f,i){
			var type=f['type'],attrs=f["attrs"],fname=prefix+f["name"];
			switch(type){
			case 4:
			case -5:
				sf={name:fname,type:typeMap[type],defaultValue:attrs["defaultValue"]||""};
				fs.push(sf);
				break;
			case 2000:
				var refModelId=attrs["refModelId"];
				FormFieldUtil.getSubModelFields(fs,refModelId,metaData,f["name"]+".");
				break;
			default:
				sf={name:fname,defaultValue:attrs["defaultValue"]};
				fs.push(sf);
				break;
			}
		});
	};
	
	FormFieldUtil.getModelFields=function(mainMetaId,metaData,prefix){
		var fs=[],refMetaMap=metaData["refMetaMap"],mainMeta=refMetaMap[mainMetaId],
		modelName="Ext.data."
		subModelIds=mainMeta["children"],prefix=prefix||"";
		if(subModelIds&&subModelIds.length>0){
			Ext.iterate(subModelIds,function(modelId,i){
				FormFieldUtil.getSubModelFields(fs,modelId,metaData,prefix);
			});
		}else{
			FormFieldUtil.getSubModelFields(fs,mainMetaId,metaData,prefix);
		}
		return fs;
	};
	
	
	FormFieldUtil.collectGroupFields=function(fields){
		var rs={};
		Ext.iterate(fields,function(f,i){
			var attrs=f["attrs"],groupName=attrs["groupName"];
			if(groupName){
				var array=rs[groupName]=rs[groupName]||[];
				array.push(f);
			}
		});
		return rs;
	};
	
	FormFieldUtil.getTagField=function(field,metaData){
		var item={xtype:"tagfield"},attrs=field['attrs']||{};
		
		item["store"]= {
           data:[
        	   ['sid','sid'],
        	   ['unid','unid']
           ],
           fields:['name','text']
        };
		
		Ext.apply(item,{
			displayField: 'text',
	        valueField: 'name',
	        filterPickList: true,
	        queryMode: 'local',
	        publishes: 'value'
		});
	};
	
	FormFieldUtil.getFormFields=function(mainMetaId,metaData,prefix){
		var items=this.items=[],
		refEnumMap=metaData["refEnumMap"],
		itemMap={},
		refMetaMap=metaData["refMetaMap"],
		mainMeta=refMetaMap[mainMetaId],
		fs=mainMeta["fields"],
		attrs=mainMeta["attrs"],
		idProperty=attrs["idProperty"],
		parentIdProperty=attrs["parentIdProperty"],
		seqProperty=attrs["seqProperty"],
		moduleProperty=attrs["moduleProperty"];
		var prefix=prefix||"",groupShow=FormFieldUtil.collectGroupFields(fs),gfs=[];
		Ext.iterate(groupShow,function(k,v,n){
			var xitem={xtype:"segmentedbutton",items:[],allowMultiple:true},pitems=xitem["items"],
			ritems=[xitem],
			item={xtype:"fieldcontainer",items:ritems,fieldLabel:"&nbsp;"};
			if(v&&v.length>0){
				Ext.iterate(v,function(f,i){
					var attrs=f["attrs"],pname=prefix+f["name"],itemid=pname.replace(/\./g,"_");
					pitems.push({
						xtype:"button",
						iconCls:attrs["iconCls"],
						itemId:itemid,
						tooltip:f["text"],
						listeners:{
							'toggle':function(button,state,event){
								this.up('form').getForm().findField(pname).setValue(state?"true":"");
							}
						}
					});
					ritems.push({
						xtype:'hidden',
						name:pname,
						listeners:{
							'change' :function (f, newValue, oldValue, eOpts ) {
								var c=this.up('form').down("#"+itemid),state=(newValue=="true");
								c.setPressed(state);
							}
						
						}
					});
					gfs.push(pname);
				});
			}
			items.push(item);
		});
		Ext.iterate(fs,function(f,i){
			var attrs=f["attrs"],item={xtype:"textfield",labelAlign:"right"},
			type=f["type"],widget=attrs["widget"],
			enums=attrs["enums"],picker=attrs["picker"];
			item["fieldLabel"]=f["text"];
			var fname=item["name"]=prefix+f["name"];
			itemMap[fname]=item;
			if(attrs["defaultValue"]){
				item["defaultValue"]=attrs["defaultValue"];
			}
			if(enums){
				if(widget){
					switch(widget){
					case "segmentedbutton":
						Ext.apply(item,FormFieldUtil.getSegmentedButton(fname,f,metaData));
						break;
					}
				}else{
					var enumdata=refEnumMap[enums];
					if(!enumdata){
						enumdata=[];
					}
					item["xtype"]='combo';
					item["queryMode"]='local';
					item["valueField"]=attrs["valueField"]||"code";
					item["displayField"]=attrs["displayField"]||"text";
					
					item["forceSelection"]=false;
					item["store"]={
						fields:["sid","name","code","text"],
						data:enumdata["list"]
					};
					item["triggerAction"]="all";
				}
			}else if(picker){
				if(picker=="treepicker"){
					item=FormFieldUtil.getTreePicker(f,metaData);
				}else{
					item=FormFieldUtil.getTrigger(f,metaData);
				}
			}else{
				switch(type){
				case 1:
					break;
				case 12:
					item["xtype"]="textarea";
					break;
				case 4:
				case -5:
					item["xtype"]='numberfield';
					item["allowNull"]=true;
					break;
				case 16:
					if(!Ext.Array.contains(gfs,fname)){
						Ext.apply(item,{
				            xtype: 'radiogroup',
				            cls: 'x-check-group-alt',
				            columns: 3,
				            items: [
				                {boxLabel: '是', inputValue: true},
				                {boxLabel: '否', inputValue: false}
				            ]
				        });
					}else{
						item=null;
					}
					break;
				case 2000:
					var refModelId=attrs["refModelId"];
					Ext.apply(item,{
						xtype:'fieldset',
						title:f["text"],
						items:FormFieldUtil.getFormFields(refModelId,metaData,fname+".")
					});
					break;
				case 2003:
					
					break;
				case 91:
					item["xtype"]='datefield';
					item["format"]='Y-m-d';
					break;
				case 92:
					item["xtype"]='timefield';
					item["format"]='h:i:s';
					break;
				case 93:
					item["xtype"]='datefield';
					item["format"]='Y-m-d h:i:s';
					break;
				}
			}
			if(item){
				items.push(item);
			}
		});
		
		if(moduleProperty){
			var moduleField=itemMap[moduleProperty];
			if(moduleField){
				moduleField["hidden"]=true;
				moduleField["readOnly"]=true;
			}
			
		}
		return items;
	};
	
	FormFieldUtil.getDisplayForm=function(metaData){
		var fields=metaData["fields"],
		items=getFormFields(metaData);
		Ext.iterate(items,function(n,i){
			item["readOnly"]=true;
		});
		var form={
				xtype:"form",
				items:items
		}
		return form;
	};
	exports.FormFieldUtil=FormFieldUtil;
	
})(Ext,window);